package com.baijia.authentication.principal;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.util.StringUtils;

import com.baijia.authentication.principal.Response.ResponseType;
import com.baijia.services.RegisteredService;
import com.baijia.util.HttpClient;

/**
 * @title SimpleWebApplicationServiceImpl
 * @desc 被302到passport的请求，被封装成一个service，用于后续校验
 * @author caoliang
 * @date 2015年12月5日
 * @version 1.0
 */
public final class SimpleWebApplicationServiceImpl extends AbstractWebApplicationService {

    private static final String CONST_PARAM_SERVICE = "service";

    private static final String CONST_PARAM_TARGET_SERVICE = "targetService";

    private static final String CONST_PARAM_TICKET = "pp_ticket";

    private static final String CONST_PARAM_METHOD = "method";

    private final ResponseType responseType;

    private static final long serialVersionUID = 8334068957483758042L;

    public SimpleWebApplicationServiceImpl(final String id) {
        this(id, id, null, null, null);
    }

    public SimpleWebApplicationServiceImpl(final String id, final HttpClient httpClient) {
        this(id, id, null, null, httpClient);
    }

    private SimpleWebApplicationServiceImpl(final String id, final String originalUrl, final String artifactId,
        final ResponseType responseType, final HttpClient httpClient) {
        super(id, originalUrl, artifactId, httpClient);
        this.responseType = responseType;
    }

    public static SimpleWebApplicationServiceImpl createServiceFrom(final HttpServletRequest request) {
        return createServiceFrom(request, null);
    }

    public static SimpleWebApplicationServiceImpl createServiceFrom(final HttpServletRequest request,
        final HttpClient httpClient) {

        final String targetService = decodeUrl(request.getParameter(CONST_PARAM_TARGET_SERVICE));
        final String serviceToUse =
            StringUtils.hasText(targetService) ? targetService : decodeUrl(request.getParameter(CONST_PARAM_SERVICE));

        final String method = request.getParameter(CONST_PARAM_METHOD);

        if (!StringUtils.hasText(serviceToUse)) {
            return null;
        }

        final String id = cleanupUrl(serviceToUse);
        final String artifactId = request.getParameter(CONST_PARAM_TICKET);

        return new SimpleWebApplicationServiceImpl(id, serviceToUse, artifactId,
            "POST".equals(method) ? ResponseType.POST : ResponseType.REDIRECT, httpClient);
    }

    private final static String decodeUrl(final String url) {
        if (url == null) {
            return null;
        }

        try {
            return URLDecoder.decode(url, "UTF-8");
        } catch (final UnsupportedEncodingException e) {
            return url;
        }
    }

    @Override
    public Response getResponse(final String ticketId) {
        final Map<String, String> parameters = new HashMap<String, String>();

        if (StringUtils.hasText(ticketId)) {
            parameters.put(CONST_PARAM_TICKET, ticketId);
        }

        if (ResponseType.POST == this.responseType) {
            return Response.getPostResponse(getOriginalUrl(), parameters);
        }
        return Response.getRedirectResponse(getOriginalUrl(), parameters);
    }

    public boolean validDomain(RegisteredService rService) {
        if (rService != null) {
            for (String allowDomain : rService.getAllowDomains()) {
                if (getOriginalUrl().contains(allowDomain)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static SimpleWebApplicationServiceImpl createDefaultService(HttpServletRequest request,
        String defaultTargetService) {
        final String method = request.getParameter(CONST_PARAM_METHOD);
        final String serviceToUse = decodeUrl(defaultTargetService);
        final String id = cleanupUrl(serviceToUse);
        final String artifactId = request.getParameter(CONST_PARAM_TICKET);

        return new SimpleWebApplicationServiceImpl(id, serviceToUse, artifactId,
            "POST".equals(method) ? ResponseType.POST : ResponseType.REDIRECT, null);
    }
}
